package com.unswift.generics.project;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.github.difflib.text.DiffRow;
import com.github.difflib.text.DiffRow.Tag;
import com.unswift.QuickApplication;
import com.unswift.annotation.api.Api;
import com.unswift.annotation.api.ApiField;
import com.unswift.annotation.api.ApiMethod;
import com.unswift.constant.QuickConstant;
import com.unswift.utils.DateUtils;
import com.unswift.utils.DbSession;
import com.unswift.utils.DbSession.FindDataBack;
import com.unswift.utils.ExceptionUtils;
import com.unswift.utils.FileUtils;
import com.unswift.utils.FreemarkerUtils;
import com.unswift.utils.JsonUtils;
import com.unswift.utils.ObjectUtils;
import com.unswift.utils.StringUtils;
import com.unswift.utils.SystemUtils;
import com.unswift.window.factory.MessageFactory;

@Api(value="创建项目工厂")
public class ProjectFactory {

	public static void generics(ProjectConfig config) {
		String templatePath=QuickApplication.getBasePath()+"/template/project";
		File rootFile=new File(templatePath);
		File[] fileList=rootFile.listFiles();
		String excludeSuffix=QuickApplication.getConfig(QuickConstant.CONF_TEMPLATE_EXCLUDE_SUFFIX);
		System.out.println(excludeSuffix);
		genericsFile(config, fileList, "", excludeSuffix.split("\\,"));
	}
	
	public static boolean genericsFile(ProjectConfig config, File[] fileList, String parentTemplatePath, String[] excludeSuffixs){
		if(ObjectUtils.isEmpty(fileList)){
			return false;
		}
		String targetFileContent;
		String targetFilePath;
		String fileName;
		for (File file : fileList) {
			fileName=file.getName();
			if(file.isDirectory()){
				boolean exists=genericsFile(config, file.listFiles(), parentTemplatePath+file.getName()+"\\", excludeSuffixs);
				if(!exists){//如果没有孩子，则生成目录
					if(parentTemplatePath.startsWith("cloud\\")){
						targetFilePath=config.getProjectPath()+parentTemplatePath.substring("cloud\\".length()).replace("com\\unswift\\cloud", config.getProjectDomain().replace(".", "\\"))+fileName;
						System.out.println("生成项目目录："+targetFilePath);
						new File(targetFilePath).mkdirs();
					}
				}
			}else{
				System.out.println(parentTemplatePath);
				if(parentTemplatePath.startsWith("cloud\\")){
					targetFilePath=config.getProjectPath()+parentTemplatePath.substring("cloud\\".length()).replace("com\\unswift\\cloud", config.getProjectDomain().replace(".", "\\"))+fileName;
					System.out.println("生成项目文件："+targetFilePath);
					if(StringUtils.endsWiths(fileName, excludeSuffixs)){
						FileUtils.copy(file, new File(targetFilePath), false);
					}else{
						targetFileContent=FreemarkerUtils.getTemplate(parentTemplatePath+"\\"+file.getName(), config);
						FileUtils.writer(targetFilePath, targetFileContent, "UTF-8", false);
					}
				}
			}
		}
		return true;
	}
	
	public static boolean genericsFile(ServerRule config, File[] fileList, String parentTemplatePath, String[] excludeSuffixs){
		File projectFile=new File(config.getProjectPath());
		ExceptionUtils.falseException(projectFile.exists(), "project.path.not.exist", config.getProjectPath());
		projectFile=new File(config.getProjectPath()+"pom.xml");
		ExceptionUtils.falseException(projectFile.exists(), "must.maven.project", config.getProjectPath());
		String content=FileUtils.reader(projectFile, "UTF-8");
		StringBuilder pom=new StringBuilder();
		if(content.contains("</modules>")){
			int first=content.indexOf("<modules>");
			int last=content.indexOf("</modules>");
			String modules=content.substring(first, last);
			if(modules.contains(config.getServerFileName())){//已经存在了
				pom.append(content);
			}else{
				pom.append(content.substring(0, last));
				pom.append("\t").append("<module>").append(config.getServerFileName()).append("</module>").append(FileUtils.nextLine()).append("\t");
				pom.append(content.substring(last));
			}
		}else{
			int index=content.lastIndexOf("</project>");
			pom.append(content.substring(0, index));
			pom.append("\t").append("<modules>").append(FileUtils.nextLine());
			pom.append("\t\t").append("<module>").append(config.getServerFileName()).append("</module>").append(FileUtils.nextLine());
			pom.append("\t").append("</modules>").append(FileUtils.nextLine());
			pom.append(content.substring(index));
		}
		FileUtils.writer(projectFile, pom.toString(), "UTF-8", false);
		
		if(ObjectUtils.isEmpty(fileList)){
			return false;
		}
		String targetFileContent;
		String targetFilePath;
		String fileName;
		for (File file : fileList) {
			fileName=file.getName();
			if(file.isDirectory()){
				boolean exists=genericsFile(config, file.listFiles(), parentTemplatePath+file.getName()+"/", excludeSuffixs);
				if(!exists){//如果没有孩子，则生成目录
					if(parentTemplatePath.startsWith("server/cloud/")){
						targetFilePath=config.getProjectPath()+config.getServerFileName()+"/"+parentTemplatePath.substring("server/cloud/".length()).replace("com\\unswift\\cloud", config.getProjectDomain().replace(".", "/"))+fileName;
						System.out.println("生成项目目录："+targetFilePath);
						new File(targetFilePath).mkdirs();
					}
				}
			}else{
				System.out.println(parentTemplatePath);
				if(parentTemplatePath.startsWith("server/cloud/")){
					targetFilePath=config.getProjectPath()+config.getServerFileName()+"/"+parentTemplatePath.substring("server/cloud/".length()).replace("com\\unswift\\cloud", config.getProjectDomain().replace(".", "/"))+fileName;
					if(fileName.endsWith("Application.java")){
						targetFilePath=targetFilePath.replace("Application.java", config.getServerClassName()+"Application.java");
					}
					System.out.println("生成项目文件："+targetFilePath);
					if(StringUtils.endsWiths(fileName, excludeSuffixs)){
						FileUtils.copy(file, new File(targetFilePath), false);
					}else{
						targetFileContent=FreemarkerUtils.getTemplate(parentTemplatePath+file.getName(), config);
						FileUtils.writer(targetFilePath, targetFileContent, "UTF-8", false);
					}
				}
			}
		}
		return true;
	}
	
	public static void genericsServer(ServerRule rule){
		String templatePath=QuickApplication.getBasePath()+"/template/server";
		File rootFile=new File(templatePath);
		File[] fileList=rootFile.listFiles();
		String excludeSuffix=QuickApplication.getConfig(QuickConstant.CONF_TEMPLATE_EXCLUDE_SUFFIX);
		System.out.println(excludeSuffix);
		genericsFile(rule, fileList, rootFile.getName()+"/", excludeSuffix.split("\\,"));
	}
	
	@SuppressWarnings("unchecked")
	@ApiMethod(value="将数据库表转换为java代码", params=@ApiField("生成JavaCode规则"), returns=@ApiField("生成结果{true:成功，false:失败}"))
	public static String genericsModule(ModuleRule rule){
		StringBuilder genericsFilePaths=new StringBuilder();
		
		String coreEntityFields=QuickApplication.getConfig(QuickConstant.CONF_POJO_CORE_FIELDS);
		String baseEntityFields=QuickApplication.getConfig(QuickConstant.CONF_POJO_BASE_FIELDS);
		String sortEntityFields=QuickApplication.getConfig(QuickConstant.CONF_POJO_SORT_FIELDS);
		
		rule.setCurrModule(handleSubModule(rule.getCurrModule()));
		
		Map<String, Object> model=new HashMap<String, Object>();
		String entityName = initModel(rule, model);
		List<Column> columnList = getColumnList(rule);
		if(ObjectUtils.isEmpty(columnList)){
			MessageFactory.error(QuickApplication.getWindow(), String.format("无法找到表%s的列", rule.getTable()));
		}
		model.put("fieldList", columnList);
		model.put("autoIncrement", null);
		List<Column> autoIncrement=columnList.stream().filter(c -> c.isAutoIncrement()).collect(Collectors.toList());
		if(ObjectUtils.isNotEmpty(autoIncrement)){
			model.put("autoIncrement", autoIncrement.get(0));
		}
		Map<String, String> parentEntity=findParentEntity(columnList, coreEntityFields, baseEntityFields, sortEntityFields);
		model.put("extend", parentEntity.get("extend"));
		model.put("pkType", parentEntity.get("pkType"));
		model.put("isDelete", isExistsIsDeleteField(columnList));
		if(rule.getGenericsModuleList().contains("pojo")){
			genericsPojo(rule, genericsFilePaths, model, entityName, columnList, parentEntity);
		}
		model.put("dataOperator", rule.getDataOperator());
		model.put("primaryKeyList", columnList.stream().filter(column -> ObjectUtils.isNotNull(column.getPrimaryKey()) && column.getPrimaryKey()).collect(Collectors.toList()));
		String subModule=ObjectUtils.init(rule.getCurrModule(), "");
		model.put("currModule", subModule);
		if(rule.getGenericsModuleList().contains("mapper")){
			genericsMapper(rule, genericsFilePaths, model, entityName, columnList, subModule);//Mapper
			Map<String, Object> soModel = genericsPojoSearchDo(rule, genericsFilePaths, model, entityName, subModule);//So
			genericsPojoPageDo(rule, genericsFilePaths, entityName, subModule, soModel);//PageSo
			genericsPojoBigDataDo(rule, genericsFilePaths, entityName, subModule, soModel);//PageSo
			genericsPojoViewDo(rule, genericsFilePaths, model, entityName, subModule);//PageSo
			genericsPojoInsertDo(rule, genericsFilePaths, model, entityName, subModule);//PageSo
			genericsPojoInsertBatchDo(rule, genericsFilePaths, model, entityName, subModule);//PageSo
			genericsPojoUpdateDo(rule, genericsFilePaths, model, entityName, subModule);//PageSo
			genericsPojoUpdateBatchDo(rule, genericsFilePaths, model, entityName, subModule);//PageSo
			genericsPojoDeleteDo(rule, genericsFilePaths, model, entityName, subModule);//PageSo
			genericsPojoDeleteBatchDo(rule, genericsFilePaths, model, entityName, subModule);//PageSo
		}
		boolean isAdapter=false;
		if(rule.getGenericsModuleList().contains("adapter")){
			genericsAdapter(rule, genericsFilePaths, model, entityName);
			isAdapter=true;
		}
		boolean exportSame=rule.getServer().equals(rule.getServerExport());
		model.put("exportSame", exportSame);
		if(rule.getGenericsModuleList().contains("service")){
			genericsService(rule, genericsFilePaths, model, entityName);
			isAdapter=true;
		}
		boolean isController=false;
		if(rule.getGenericsModuleList().contains("controller")){
			genericsController(rule, genericsFilePaths, model, entityName);
			isController=true;
		}
		if(!exportSame && rule.getGenericsModuleList().contains("controller") && (rule.getDataOperator().contains("export") || rule.getDataOperator().contains("import"))){
			genericsExportService(rule, genericsFilePaths, model, entityName);
			if(rule.getDataOperator().contains("import")) {
				genericsImportService(rule, genericsFilePaths, model, entityName);
			}
			genericsExportController(rule, genericsFilePaths, model, entityName);
		}
		genericsFilePaths.append(FileUtils.nextLine());
		List<String> importList = (List<String>)model.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			model.put("importList", importList);
		}
		columnList.forEach(c -> {
			if(c.getFieldSampleName().equals("sort")) {
				c.setGenericsField(true);
			}
		});
		if(isAdapter){
			if(rule.getDataOperator().contains("list")){
				genericsPageSearchBo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("view")){
				genericsViewBo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("create")){
				genericsCreateBo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("update")){
				genericsUpdateBo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("delete")){
				genericsDeleteBo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("export")){
				genericsExportBo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("import")){
				genericsImportBo(rule, genericsFilePaths, model, entityName, subModule);
			}
			genericsFilePaths.append(FileUtils.nextLine());
		}
		if(isController){
			if(rule.getDataOperator().contains("list")){
				genericsPageSearchDto(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("view")){
				genericsViewDto(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("create")){
				genericsCreateDto(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("update")){
				genericsUpdateDto(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("delete")){
				genericsDeleteDto(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("export")){
				genericsExportDto(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("import")){
				genericsImportDto(rule, genericsFilePaths, model, entityName, subModule);
			}
			genericsFilePaths.append(FileUtils.nextLine());
		}
		if(isAdapter || isController){
			if(rule.getDataOperator().contains("list")){
				genericsPageListVo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("view")){
				genericsViewVo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("create")){
				genericsCreateVo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("update")){
				genericsUpdateVo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("delete")){
				genericsDeleteVo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("export")){
				genericsExportVo(rule, genericsFilePaths, model, entityName, subModule);
			}
			if(rule.getDataOperator().contains("import")){
				genericsImportVo(rule, genericsFilePaths, model, entityName, subModule);
			}
		}
		return genericsFilePaths.toString();
	}

	private static void genericsDeleteVo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> voModel=ObjectUtils.copyMap(model);
		voModel.remove("importList");
		voModel.put("entityName", entityName+"DeleteVo");
		voModel.put("tableComment", rule.getTableComment()+"删除返回实体");
		voModel.put("extend", "BaseVo");
		String content=FreemarkerUtils.getTemplate("module/cloud/VoOperator.ftl", voModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"DeleteVo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("DeleteVo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsUpdateVo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> voModel=ObjectUtils.copyMap(model);
		voModel.remove("importList");
		voModel.put("entityName", entityName+"UpdateVo");
		voModel.put("tableComment", rule.getTableComment()+"更新返回实体");
		voModel.put("extend", "BaseVo");
		String content=FreemarkerUtils.getTemplate("module/cloud/VoOperator.ftl", voModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateVo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("UpdateVo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsCreateVo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> voModel=ObjectUtils.copyMap(model);
		voModel.remove("importList");
		voModel.put("entityName", entityName+"CreateVo");
		voModel.put("tableComment", rule.getTableComment()+"新建返回实体");
		voModel.put("extend", "BaseVo");
		String content=FreemarkerUtils.getTemplate("module/cloud/VoOperator2.ftl", voModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"CreateVo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("CreateVo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsViewVo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", entityName+"ViewVo");
		model.put("isPrimaryKey", true);
		model.put("tableComment", rule.getTableComment()+"详情返回实体");
		model.put("extend", "BaseVo");
		String content=FreemarkerUtils.getTemplate("module/cloud/Vo.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ViewVo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ViewVo类："+entityPath).append(FileUtils.nextLine());
	}
	
	@SuppressWarnings("unchecked")
	private static void genericsExportVo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", entityName+"ExportVo");
		model.put("isPrimaryKey", false);
		model.put("exportComment", rule.getTableComment());
		model.put("tableComment", rule.getTableComment()+"导出返回实体");
		model.put("extend", "BaseVo");
		String content=FreemarkerUtils.getTemplate("module/cloud/VoExport.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportVo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ExportVo类："+entityPath).append(FileUtils.nextLine());
		
		Map<String, Object> moModel=ObjectUtils.copyMap(model);
		moModel.put("entityName", entityName+"ExportMo");
		moModel.put("isPrimaryKey", false);
		moModel.put("exportComment", rule.getTableComment());
		moModel.put("tableComment", rule.getTableComment()+"导出模板实体");
		moModel.put("extend", "BaseMo");
		List<String> importList=(List<String>)moModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)) {
			importList=importList.stream().filter(i -> !i.contains("Serialize") && !i.contains("JsonFormat")).collect(Collectors.toList());
			moModel.put("importList", importList);
		}
		
		content=FreemarkerUtils.getTemplate("module/cloud/MoExport.ftl", moModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/mo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportMo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ExportModelVo类："+entityPath).append(FileUtils.nextLine());
		
		model.put("entityName", entityName+"ExportStopVo");
		model.put("isPrimaryKey", false);
		model.put("exportComment", rule.getTableComment());
		model.put("tableComment", rule.getTableComment()+"停止导出实体");
		model.put("extend", "BaseVo");
		content=FreemarkerUtils.getTemplate("module/cloud/VoOperator.ftl", model);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportStopVo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ExportStopVo类："+entityPath).append(FileUtils.nextLine());
	}
	
	@SuppressWarnings("unchecked")
	private static void genericsImportVo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", entityName+"ImportVo");
		model.put("isPrimaryKey", false);
		model.put("exportComment", rule.getTableComment());
		model.put("tableComment", rule.getTableComment()+"导入返回实体");
		model.put("extend", "BaseVo");
		String content=FreemarkerUtils.getTemplate("module/cloud/VoExport.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportVo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ImportVo类："+entityPath).append(FileUtils.nextLine());
		
		Map<String, Object> moModel=ObjectUtils.copyMap(model);
		moModel.put("entityName", entityName+"ImportMo");
		moModel.put("isPrimaryKey", false);
		moModel.put("exportComment", rule.getTableComment());
		moModel.put("tableComment", rule.getTableComment()+"导入模板实体");
		moModel.put("extend", "ImportMo");
		List<String> importList=(List<String>)moModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)) {
			importList=importList.stream().filter(i -> !i.contains("Serialize") && !i.contains("JsonFormat")).collect(Collectors.toList());
			moModel.put("importList", importList);
		}
		content=FreemarkerUtils.getTemplate("module/cloud/MoImport.ftl", moModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/mo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportMo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ImportModelVo类："+entityPath).append(FileUtils.nextLine());
		
		model.put("entityName", entityName+"ImportStopVo");
		model.put("isPrimaryKey", false);
		model.put("exportComment", rule.getTableComment());
		model.put("tableComment", rule.getTableComment()+"停止导入实体");
		model.put("extend", "BaseVo");
		content=FreemarkerUtils.getTemplate("module/cloud/VoOperator.ftl", model);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportStopVo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ImportStopVo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsPageListVo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", entityName+"PageVo");
		model.put("isPrimaryKey", true);
		model.put("tableComment", rule.getTableComment()+"分页查询返回实体");
		model.put("extend", "BaseVo");
		String content=FreemarkerUtils.getTemplate("module/cloud/Vo.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageVo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("PageVo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsDeleteDto(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> dtoModel=ObjectUtils.copyMap(model);
		dtoModel.remove("importList");
		dtoModel.put("entityName", entityName+"DeleteDto");
		dtoModel.put("tableComment", rule.getTableComment()+"删除Dto实体");
		dtoModel.put("extend", "BaseDto");
		String content=FreemarkerUtils.getTemplate("module/cloud/DtoOperator.ftl", dtoModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"DeleteDto.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("DeleteDto类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsUpdateDto(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", entityName+"UpdateDto");
		model.put("isPrimaryKey", true);
		model.put("tableComment", rule.getTableComment()+"更新Dto实体");
		model.put("extend", "BaseDto");
		String content=FreemarkerUtils.getTemplate("module/cloud/Dto.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateDto.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("UpdateDto类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsCreateDto(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", entityName+"CreateDto");
		model.put("isPrimaryKey", false);
		model.put("tableComment", rule.getTableComment()+"新建Dto实体");
		model.put("extend", "BaseDto");
		String content=FreemarkerUtils.getTemplate("module/cloud/Dto.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"CreateDto.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("CreateDto类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsViewDto(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> dtoModel=ObjectUtils.copyMap(model);
		dtoModel.remove("importList");
		dtoModel.put("entityName", entityName+"ViewDto");
		dtoModel.put("tableComment", rule.getTableComment()+"详情Dto实体");
		dtoModel.put("extend", "BaseDto");
		String content=FreemarkerUtils.getTemplate("module/cloud/DtoOperator.ftl", dtoModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ViewDto.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ViewDto类："+entityPath).append(FileUtils.nextLine());
	}
	
	private static void genericsExportDto(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", ""+entityName+"ExportDto");
		model.put("isPrimaryKey", true);
		model.put("tableComment", rule.getTableComment()+"导出查询Dto实体");
		model.put("extend", "PageDto");
		String content=FreemarkerUtils.getTemplate("module/cloud/Dto.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportDto.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ExportStopDto类："+entityPath).append(FileUtils.nextLine());
		
		Map<String, Object> dtoModel=ObjectUtils.copyMap(model);
		dtoModel.put("importList", null);
		dtoModel.put("entityName", ""+entityName+"ExportStopDto");
		dtoModel.put("isPrimaryKey", true);
		dtoModel.put("tableComment", rule.getTableComment()+"停止导出Dto实体");
		dtoModel.put("extend", "BaseDto");
		content=FreemarkerUtils.getTemplate("module/cloud/DtoOperator.ftl", dtoModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportStopDto.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ExportStopDto类："+entityPath).append(FileUtils.nextLine());
	}
	
	private static void genericsImportDto(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", ""+entityName+"ImportDto");
		model.put("isPrimaryKey", true);
		model.put("tableComment", rule.getTableComment()+"导入查询Dto实体");
		model.put("extend", "PageDto");
		String content=FreemarkerUtils.getTemplate("module/cloud/DtoImport.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportDto.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ImportStopDto类："+entityPath).append(FileUtils.nextLine());
		
		Map<String, Object> dtoModel=ObjectUtils.copyMap(model);
		dtoModel.put("importList", null);
		dtoModel.put("entityName", ""+entityName+"ImportStopDto");
		dtoModel.put("isPrimaryKey", true);
		dtoModel.put("tableComment", rule.getTableComment()+"停止导入Dto实体");
		dtoModel.put("extend", "BaseDto");
		content=FreemarkerUtils.getTemplate("module/cloud/DtoOperator.ftl", dtoModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportStopDto.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ImportStopDto类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsPageSearchDto(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", ""+entityName+"PageDto");
		model.put("isPrimaryKey", true);
		model.put("tableComment", rule.getTableComment()+"分页查询Dto实体");
		model.put("extend", "PageDto");
		String content=FreemarkerUtils.getTemplate("module/cloud/Dto.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageDto.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("PageDto类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsDeleteBo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> boModel=ObjectUtils.copyMap(model);
		boModel.remove("importList");
		boModel.put("entityName", entityName+"DeleteBo");
		boModel.put("tableComment", rule.getTableComment()+"删除业务实体");
		boModel.put("extend", "BaseBo");
		String content=FreemarkerUtils.getTemplate("module/cloud/BoOperator.ftl", boModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"DeleteBo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("DeleteBo类："+entityPath).append(FileUtils.nextLine());
	}
	
	private static void genericsExportBo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> boModel=ObjectUtils.copyMap(model);
		boModel.put("entityName", entityName+"ExportBo");
		boModel.put("tableComment", rule.getTableComment()+"导出业务实体");
		boModel.put("extend", "BaseBo");
		String content=FreemarkerUtils.getTemplate("module/cloud/Bo.ftl", boModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportBo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ExportBo类："+entityPath).append(FileUtils.nextLine());
		
		boModel.remove("importList");
		boModel.put("entityName", entityName+"ExportStopBo");
		boModel.put("tableComment", rule.getTableComment()+"停止导出业务实体");
		boModel.put("extend", "BaseBo");
		content=FreemarkerUtils.getTemplate("module/cloud/BoOperator.ftl", boModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportStopBo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ExportStopBo类："+entityPath).append(FileUtils.nextLine());
	}
	
	private static void genericsImportBo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> boModel=ObjectUtils.copyMap(model);
		boModel.put("entityName", entityName+"ImportBo");
		boModel.put("tableComment", rule.getTableComment()+"导入业务实体");
		boModel.put("extend", "BaseBo");
		String content=FreemarkerUtils.getTemplate("module/cloud/BoImport.ftl", boModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportBo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ImportBo类："+entityPath).append(FileUtils.nextLine());
		
		boModel.remove("importList");
		boModel.put("entityName", entityName+"ImportStopBo");
		boModel.put("tableComment", rule.getTableComment()+"停止导入业务实体");
		boModel.put("extend", "BaseBo");
		content=FreemarkerUtils.getTemplate("module/cloud/BoOperator.ftl", boModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportStopBo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ImportStopBo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsUpdateBo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", entityName+"UpdateBo");
		model.put("isPrimaryKey", true);
		model.put("tableComment", rule.getTableComment()+"更新业务实体");
		model.put("extend", "BaseBo");
		String content=FreemarkerUtils.getTemplate("module/cloud/Bo.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateBo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("UpdateBo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsCreateBo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		model.put("entityName", entityName+"CreateBo");
		model.put("isPrimaryKey", false);
		model.put("tableComment", rule.getTableComment()+"新建业务实体");
		model.put("extend", "BaseBo");
		String content=FreemarkerUtils.getTemplate("module/cloud/Bo.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"CreateBo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("CreateBo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsViewBo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, String subModule) {
		Map<String, Object> boModel=ObjectUtils.copyMap(model);
		boModel.remove("importList");
		boModel.put("entityName", entityName+"ViewBo");
		boModel.put("tableComment", rule.getTableComment()+"详情业务实体");
		boModel.put("extend", "BaseBo");
		String content=FreemarkerUtils.getTemplate("module/cloud/BoOperator.ftl", boModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ViewBo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("ViewBo类："+entityPath).append(FileUtils.nextLine());
	}

	private static void genericsPageSearchBo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		model.put("entityName", entityName+"PageBo");
		model.put("isPrimaryKey", true);
		model.put("tableComment", rule.getTableComment()+"分页查询业务实体");
		model.put("extend", "PageBo");
		String content=FreemarkerUtils.getTemplate("module/cloud/Bo.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageBo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("PageBo类："+entityPath).append(FileUtils.nextLine());
	}

	private static List<Column> getColumnList(ModuleRule rule) {
		List<Column> columnList=new ArrayList<Column>();
		DbSession.find("select column_name columnName,data_type columnType,"
				+ "ifnull(character_maximum_length, numeric_precision) columnLength,numeric_scale columnScale,"
				+ "(case when column_key='PRI' then true else false end) primaryKey,column_comment columnComment, "
				+ "(case when extra='auto_increment' then true else false end) autoIncrement "
				+ "from information_schema.`columns` where table_schema=? and table_name=? order by ordinal_position asc", new FindDataBack() {
			@Override
			public boolean handleRow(Map<String, Object> rowData, int row) {
				Column column = JsonUtils.toJava(JsonUtils.toJson(rowData), Column.class);
				column.setFieldSampleName(StringUtils.underlineToHump(column.getColumnName()));
				column.setColumnAlias("`"+column.getFieldSampleName()+"`");
				column.setFieldName(StringUtils.toFirstUpper(column.getFieldSampleName()));
				columnTypeToJavaType(column, rule.getBasePackage());
				column.setGenericsField(true);
				columnList.add(column);
				return super.handleRow(rowData, row);
			}
		}, rule.getDatabase(), rule.getTable());
		return columnList;
	}

	private static String initModel(ModuleRule rule, Map<String, Object> model) {
		model.put("date", DateUtils.format("yyyy-MM-dd"));
		model.put("username", SystemUtils.getSystemName());
		model.put("basePackage", rule.getBasePackage());
		model.put("module", rule.getModule());
		String removedPrefixTable;
		if(ObjectUtils.isNotEmpty(rule.getIgnorePrefix())){
			removedPrefixTable=rule.getTable().startsWith(rule.getIgnorePrefix())?rule.getTable().substring(rule.getIgnorePrefix().length()):rule.getTable();
		}else{
			removedPrefixTable=rule.getTable();
		}
		model.put("table", rule.getTable());
		String entitySampleName=StringUtils.underlineToHump(removedPrefixTable);
		String entityName=StringUtils.toFirstUpper(entitySampleName);
		model.put("entitySampleName", entitySampleName);
		model.put("entityName", entityName);
		model.put("tableComment", rule.getTableComment());
		return entityName;
	}
	
	private static void genericsExportController(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName) {
		String content=FreemarkerUtils.getTemplate("module/cloud/ControllerImexport.ftl", model);
		String controller=rule.getProjectPath()+rule.getServerExport()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/controller/"+rule.getModule()+"/"+entityName+"ImexportController.java";
		File file=new File(controller);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(controller, true);
		FileUtils.writer(controller, content, "UTF-8", false);
		genericsFilePaths.append("ExportController类："+controller).append(FileUtils.nextLine());
	}

	private static void genericsController(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName) {
		String businessModule=ObjectUtils.isNotEmpty(rule.getBusinessModule())?"/"+rule.getBusinessModule():"";
		String content=FreemarkerUtils.getTemplate("module/cloud/Controller.ftl", model);
		String controller=rule.getProjectPath()+rule.getServer()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/controller"+businessModule+"/"+entityName+"Controller.java";
		File file=new File(controller);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(controller, true);
		FileUtils.writer(controller, content, "UTF-8", false);
		genericsFilePaths.append("Controller类："+controller).append(FileUtils.nextLine());
	}
	
	private static void genericsExportService(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName) {
		String content=FreemarkerUtils.getTemplate("module/cloud/ServiceExport.ftl", model);
		String service=rule.getProjectPath()+rule.getServerExport()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/service/export/"+rule.getModule()+"/"+entityName+"ExportService.java";
		File file=new File(service);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(service, true);
		FileUtils.writer(service, content, "UTF-8", false);
		genericsFilePaths.append("Service类："+service).append(FileUtils.nextLine());
	}
	private static void genericsImportService(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName) {
		String content=FreemarkerUtils.getTemplate("module/cloud/ServiceImport.ftl", model);
		String service=rule.getProjectPath()+rule.getServerExport()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/service/imports/"+rule.getModule()+"/"+entityName+"ImportService.java";
		File file=new File(service);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(service, true);
		FileUtils.writer(service, content, "UTF-8", false);
		genericsFilePaths.append("Service类："+service).append(FileUtils.nextLine());
	}

	private static void genericsService(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName) {
		String businessModule=ObjectUtils.isNotEmpty(rule.getBusinessModule())?"/"+rule.getBusinessModule():"";
		String content=FreemarkerUtils.getTemplate("module/cloud/Service.ftl", model);
		String service=rule.getProjectPath()+rule.getServer()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/service"+businessModule+"/"+entityName+"Service.java";
		File file=new File(service);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(service, true);
		FileUtils.writer(service, content, "UTF-8", false);
		genericsFilePaths.append("Service类："+service).append(FileUtils.nextLine());
	}

	private static void genericsAdapter(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName) {
		String businessModule=ObjectUtils.isNotEmpty(rule.getBusinessModule())?"/"+rule.getBusinessModule():"";
		String content=FreemarkerUtils.getTemplate("module/cloud/Adapter.ftl", model);
		String Adapter=rule.getProjectPath()+rule.getServerAdapter()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/adapter/"+rule.getModule()+businessModule+"/"+entityName+"Adapter.java";
		File file=new File(Adapter);
		if(file.exists()){
			content = compareMerge(content, file);
		}
		FileUtils.createFile(Adapter, true);
		FileUtils.writer(Adapter, content, "UTF-8", false);
		genericsFilePaths.append("Adapter类："+Adapter).append(FileUtils.nextLine());
	}

	private static String compareMerge(String content, File file) {
		List<String> fileContentList=FileUtils.readerLine(file, "UTF-8");
		List<String> newFileContentList=FileUtils.contentToLine(content);
		List<DiffRow> compareDiffRow=FileUtils.compareLines(fileContentList, newFileContentList);
		int row=0;
		for (DiffRow diffRow : compareDiffRow) {
			if(!diffRow.getTag().equals(Tag.EQUAL)){
				String lineInfo = diffRow.getOldLine().replaceAll("<span class\\=\\\"[a-zA-Z]*\\\">", "").replace("</span>", "");
				if(diffRow.getNewLine().trim().equals(lineInfo.trim())) {
					continue;
				}
				if(lineInfo.trim().startsWith("@Api(") || lineInfo.trim().startsWith("@ApiEntity(")) {
					continue;
				}
				if(!(lineInfo.startsWith("import ") && newFileContentList.stream().filter(l -> l.equals(lineInfo)).findAny().isPresent())){
					if(row>=newFileContentList.size()){
						newFileContentList.add(newFileContentList.size()-1, lineInfo.replace("&lt;", "<").replace("&gt;", ">"));
					}else{
						newFileContentList.add(row, lineInfo.replace("&lt;", "<").replace("&gt;", ">"));
					}
				}
			}
			row++;
		}
		return FileUtils.lineToContent(newFileContentList);
	}
	
	private static void genericsPojoPageDo(ModuleRule rule, StringBuilder genericsFilePaths, String entityName,
			String subModule, Map<String, Object> soModel) {
		String content=FreemarkerUtils.getTemplate("module/cloud/DoPage.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		
		soModel.put("doType", "Data");
		soModel.put("tableDetailComment", "查询结果");
		content=FreemarkerUtils.getTemplate("module/cloud/Do.ftl", soModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"DataDo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
	}
	
	private static void genericsPojoBigDataDo(ModuleRule rule, StringBuilder genericsFilePaths, String entityName,
			String subModule, Map<String, Object> soModel) {
		String content=FreemarkerUtils.getTemplate("module/cloud/DoBigData.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"BigDataDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
	}

	@SuppressWarnings("unchecked")
	private static Map<String, Object> genericsPojoSearchDo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		Map<String, Object> soModel=ObjectUtils.copyMap(model);
		soModel.put("isPrimaryKey", false);
		List<String> importList = (List<String>)soModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			soModel.put("importList", importList);
		}
		String content=FreemarkerUtils.getTemplate("module/cloud/DoSearch.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"SearchDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		return soModel;
	}
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> genericsPojoViewDo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		Map<String, Object> soModel=ObjectUtils.copyMap(model);
		soModel.put("isPrimaryKey", false);
		List<String> importList = (List<String>)soModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			soModel.put("importList", importList);
		}
		
		soModel.put("isPrimaryKey", true);
		String content=FreemarkerUtils.getTemplate("module/cloud/DoSingle.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"SingleDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		return soModel;
	}
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> genericsPojoInsertDo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		Map<String, Object> soModel=ObjectUtils.copyMap(model);
		soModel.put("isPrimaryKey", false);
		List<String> importList = (List<String>)soModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			soModel.put("importList", importList);
		}
		soModel.put("doType", "Insert");
		soModel.put("tableDetailComment", "插入记录");
		String content=FreemarkerUtils.getTemplate("module/cloud/Do.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"InsertDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		return soModel;
	}
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> genericsPojoInsertBatchDo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		Map<String, Object> soModel=ObjectUtils.copyMap(model);
		soModel.put("isPrimaryKey", false);
		List<String> importList = (List<String>)soModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			soModel.put("importList", importList);
		}
		String content=FreemarkerUtils.getTemplate("module/cloud/DoInsertBatch.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"InsertBatchDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		
		soModel.put("doType", "InsertBatchItem");
		soModel.put("tableDetailComment", "批量插入记录");
		content=FreemarkerUtils.getTemplate("module/cloud/Do.ftl", soModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"InsertBatchItemDo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		return soModel;
	}
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> genericsPojoUpdateDo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		Map<String, Object> soModel=ObjectUtils.copyMap(model);
		soModel.put("isPrimaryKey", false);
		List<String> importList = (List<String>)soModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			soModel.put("importList", importList);
		}
		String content=FreemarkerUtils.getTemplate("module/cloud/DoUpdate.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		return soModel;
	}
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> genericsPojoUpdateBatchDo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		Map<String, Object> soModel=ObjectUtils.copyMap(model);
		soModel.put("isPrimaryKey", false);
		List<String> importList = (List<String>)soModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			soModel.put("importList", importList);
		}
		String content=FreemarkerUtils.getTemplate("module/cloud/DoUpdateBatch.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateBatchDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		
		soModel.put("doType", "UpdateBatchItem");
		soModel.put("tableDetailComment", "批量更新记录");
		content=FreemarkerUtils.getTemplate("module/cloud/Do.ftl", soModel);
		entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateBatchItemDo.java";
		file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		return soModel;
	}
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> genericsPojoDeleteDo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		Map<String, Object> soModel=ObjectUtils.copyMap(model);
		soModel.put("isPrimaryKey", true);
		List<String> importList = (List<String>)soModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			soModel.put("importList", importList);
		}
		String content=FreemarkerUtils.getTemplate("module/cloud/DoDelete.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"DeleteDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		return soModel;
	}
	
	@SuppressWarnings("unchecked")
	private static Map<String, Object> genericsPojoDeleteBatchDo(ModuleRule rule, StringBuilder genericsFilePaths,
			Map<String, Object> model, String entityName, String subModule) {
		Map<String, Object> soModel=ObjectUtils.copyMap(model);
		soModel.put("isPrimaryKey", true);
		List<String> importList = (List<String>)soModel.get("importList");
		if(ObjectUtils.isNotEmpty(importList)){
			importList=importList.stream().filter(s -> !s.startsWith(rule.getBasePackage()+".pojo.po.")).collect(Collectors.toList());
			soModel.put("importList", importList);
		}
		String content=FreemarkerUtils.getTemplate("module/cloud/DoDeleteBatch.ftl", soModel);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dao/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"DeleteBatchDo.java";
		File file=new File(entityPath);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("Do类："+entityPath).append(FileUtils.nextLine());
		return soModel;
	}

	private static void genericsMapper(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, List<Column> columnList, String subModule) {
		model.put("table", rule.getTable());
		model.put("valueBegin", "#{");
		model.put("valueBegin2", "${");
		model.put("valueEnd", "}");
		model.put("stringUtils", new StringUtils());
		List<Column> isDeleteList=columnList.stream().filter(column -> "isDelete".equals(column.getFieldSampleName())).collect(Collectors.toList());
		model.put("isDeleteField", ObjectUtils.isEmpty(isDeleteList)?null:isDeleteList.get(0));
		String content=FreemarkerUtils.getTemplate("module/cloud/Mapper.ftl", model);
		String mapper=rule.getProjectPath()+rule.getServerMapper()+"/src/main/resources/mapper/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"Mapper.xml";
		File file=new File(mapper);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(mapper, true);
		FileUtils.writer(mapper, content, "UTF-8", false);
		genericsFilePaths.append("Mapper.xml："+mapper).append(FileUtils.nextLine());
		
		model.put("moduleSample", StringUtils.toFirstUpper(rule.getModule()));
		content=FreemarkerUtils.getTemplate("module/cloud/Mapper.java.ftl", model);
		mapper=rule.getProjectPath()+rule.getServerMapper()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/mapper/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"Mapper.java";
		file=new File(mapper);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(mapper, true);
		FileUtils.writer(mapper, content, "UTF-8", false);
		genericsFilePaths.append("Mapper类："+mapper).append(FileUtils.nextLine());
		
		content=FreemarkerUtils.getTemplate("module/cloud/MapperExtend.ftl", model);
		mapper=rule.getProjectPath()+rule.getServerMapper()+"/src/main/resources/mapper/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExtendMapper.xml";
		file=new File(mapper);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(mapper, true);
		FileUtils.writer(mapper, content, "UTF-8", false);
		genericsFilePaths.append("MapperExtend.xml："+mapper).append(FileUtils.nextLine());
		
		model.put("moduleSample", StringUtils.toFirstUpper(rule.getModule()));
		content=FreemarkerUtils.getTemplate("module/cloud/MapperExtend.java.ftl", model);
		mapper=rule.getProjectPath()+rule.getServerMapper()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/mapper/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExtendMapper.java";
		file=new File(mapper);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(mapper, true);
		FileUtils.writer(mapper, content, "UTF-8", false);
		genericsFilePaths.append("Mapper扩展类："+mapper).append(FileUtils.nextLine());
		
		content=FreemarkerUtils.getTemplate("module/cloud/Sql.ftl", model);
		mapper=rule.getProjectPath()+rule.getServerMapper()+"/src/main/resources/sql/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"Sql.xml";
		file=new File(mapper);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(mapper, true);
		FileUtils.writer(mapper, content, "UTF-8", false);
		genericsFilePaths.append("自定义Sql.xml："+mapper).append(FileUtils.nextLine());
		
		content=FreemarkerUtils.getTemplate("module/cloud/Sql.java.ftl", model);
		mapper=rule.getProjectPath()+rule.getServerMapper()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/sql/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"Sql.java";
		file=new File(mapper);
		if(file.exists()){
			content=compareMerge(content, file);
		}
		FileUtils.createFile(mapper, true);
		FileUtils.writer(mapper, content, "UTF-8", false);
		genericsFilePaths.append("自定义Sql类："+mapper).append(FileUtils.nextLine());
	}

	private static void genericsPojo(ModuleRule rule, StringBuilder genericsFilePaths, Map<String, Object> model,
			String entityName, List<Column> columnList, Map<String, String> parentEntity) {
		List<String> importList=new ArrayList<String>();
		setImportList(columnList, importList);
		importList.add(parentEntity.get("import"));
		model.put("importList", importList);
		String content=FreemarkerUtils.getTemplate("module/cloud/Po.ftl", model);
		String entityPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/po/"+rule.getModule()+"/"+entityName+".java";
		FileUtils.createFile(entityPath, true);
		FileUtils.writer(entityPath, content, "UTF-8", false);
		genericsFilePaths.append("PO类："+entityPath).append(FileUtils.nextLine());
	}
	
	@ApiMethod(value="mysql的列类型转换为java对象", params=@ApiField("mysql表的列对象"))
	private static void columnTypeToJavaType(Column column, String domain){
		String type=column.getColumnType();
		if("bit".equals(type)){
			column.setFieldType("Boolean");
			column.setColumnType("BIT");
		}else if("tinyint".equals(type)){
			column.setFieldType("Byte");
			column.setColumnType("INTEGER");
		}else if("smallint".equals(type)){
			column.setFieldType("Short");
			column.setColumnType("INTEGER");
		}else if("mediumint".equals(type) || "int".equals(type) || "integer".equals(type)){
			column.setFieldType("Integer");
			column.setColumnType("INTEGER");
		}else if("bigint".equals(type)){
			column.setFieldType("Long");
			column.setColumnType("BIGINT");
		}else if("float".equals(type)){
			column.setFieldType("Decimal");
			column.setColumnType("DECIMAL");
			column.addImportPackage("java.math.BigDecimal;");
			if(column.getColumnScale()==null || column.getColumnScale()==0){
				column.setJsonFormat("@JsonSerialize(using=DecimalSerializer.class)");
				column.addImportPackage("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				column.addImportPackage(domain+".json.DecimalSerializer;");
			}else{
				column.setJsonFormat("@JsonSerialize(using=Decimal"+column.getColumnScale()+"Serializer.class)");
				column.addImportPackage("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				column.addImportPackage(domain+".json.Decimal"+column.getColumnScale()+"Serializer;");
			}
			column.setExcelFormat("#");
		}else if("double".equals(type)){
			column.setFieldType("Decimal");
			column.setColumnType("DECIMAL");
			column.addImportPackage("java.math.BigDecimal;");
			if(column.getColumnScale()==null || column.getColumnScale()==0){
				column.setJsonFormat("@JsonSerialize(using=DecimalSerializer.class)");
				column.addImportPackage("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				column.addImportPackage(domain+".json.DecimalSerializer;");
			}else{
				column.setJsonFormat("@JsonSerialize(using=Decimal"+column.getColumnScale()+"Serializer.class)");
				column.addImportPackage("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				column.addImportPackage(domain+".json.Decimal"+column.getColumnScale()+"Serializer;");
			}
			column.setExcelFormat("#");
		}else if("decimal".equals(type)){
			column.setFieldType("BigDecimal");
			column.setColumnType("DECIMAL");
			column.addImportPackage("java.math.BigDecimal;");
			if(column.getColumnScale()==null || column.getColumnScale()==0){
				column.setJsonFormat("@JsonSerialize(using=DecimalSerializer.class)");
				column.addImportPackage("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				column.addImportPackage(domain+".json.DecimalSerializer;");
			}else{
				column.setJsonFormat("@JsonSerialize(using=Decimal"+column.getColumnScale()+"Serializer.class)");
				column.addImportPackage("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				column.addImportPackage(domain+".json.Decimal"+column.getColumnScale()+"Serializer;");
			}
			column.setExcelFormat("#");
		}else if("year".equals(type)){
			column.setFieldType("Short");
			column.setColumnType("SHORT");
		}else if("date".equals(type)){
			column.setFieldType("Date");
			column.setColumnType("DATE");
			column.addImportPackage("java.util.Date;");
			column.setJsonFormat("@JsonFormat(pattern=\"yyyy-MM-dd\", timezone=\"GMT+8\")");
			column.addImportPackage("com.fasterxml.jackson.annotation.JsonFormat;");
			column.setExcelFormat("yyyy-MM-dd");
		}else if("time".equals(type)){
			column.setFieldType("Date");
			column.setColumnType("TIME");
			column.addImportPackage("java.util.Date;");
			column.setJsonFormat("@JsonFormat(pattern=\"HH:mm:ss\", timezone=\"GMT+8\")");
			column.addImportPackage("com.fasterxml.jackson.annotation.JsonFormat;");
			column.setExcelFormat("HH:mm:ss");
		}else if("datetime".equals(type)){
			column.setFieldType("Date");
			column.setColumnType("TIMESTAMP");
			column.addImportPackage("java.util.Date;");
			column.setJsonFormat("@JsonFormat(pattern=\"yyyy-MM-dd HH:mm:ss\", timezone=\"GMT+8\")");
			column.addImportPackage("com.fasterxml.jackson.annotation.JsonFormat;");
			column.setExcelFormat("yyyy-MM-dd HH:mm:ss");
		}else if("timestamp".equals(type)){
			column.setFieldType("Date");
			column.setColumnType("TIMESTAMP");
			column.addImportPackage("java.util.Date;");
			column.setJsonFormat("@JsonFormat(pattern=\"yyyy-MM-dd HH:mm:ss\", timezone=\"GMT+8\")");
			column.addImportPackage("com.fasterxml.jackson.annotation.JsonFormat;");
			column.setExcelFormat("yyyy-MM-dd HH:mm:ss");
		}else if("char".equals(type)){
			column.setFieldType("String");
			column.setColumnType("VARCHAR");
		}else{
			column.setFieldType("String");
			column.setColumnType("VARCHAR");
		}
	}
	
	@ApiMethod(value="mysql的列类型转换为java对象", params=@ApiField("mysql表的列对象"))
	private static Map<String, Object> columnTypeToJavaType(AddFieldRule rule, String domain){
		Map<String, Object> javaTypeMap=new HashMap<String, Object>();
		String type=rule.getFieldType();
		if("bit".equals(type)){
			javaTypeMap.put("javaType", "Boolean");
		}else if("tinyint".equals(type)){
			javaTypeMap.put("javaType", "Byte");
		}else if("smallint".equals(type)){
			javaTypeMap.put("javaType", "Short");
		}else if("mediumint".equals(type) || "int".equals(type) || "integer".equals(type)){
			javaTypeMap.put("javaType", "Integer");
		}else if("bigint".equals(type)){
			javaTypeMap.put("javaType", "Long");
		}else if("float".equals(type)){
			javaTypeMap.put("javaType", "Decimal");
			List<String> imports=new ArrayList<String>();
			imports.add("java.math.BigDecimal;");
			if(rule.getFieldScale()==null || rule.getFieldScale()==0){
				javaTypeMap.put("jsonFormat", "@JsonSerialize(using=DecimalSerializer.class)");
				imports.add("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				imports.add(domain+".json.DecimalSerializer;");
			}else{
				javaTypeMap.put("jsonFormat", "@JsonSerialize(using=Decimal"+rule.getFieldScale()+"Serializer.class)");
				imports.add("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				imports.add(domain+".json.Decimal"+rule.getFieldScale()+"Serializer;");
			}
			javaTypeMap.put("excelFormat", "#");
			javaTypeMap.put("imports", imports);
		}else if("double".equals(type)){
			javaTypeMap.put("javaType", "Decimal");
			List<String> imports=new ArrayList<String>();
			imports.add("java.math.BigDecimal;");
			if(rule.getFieldScale()==null || rule.getFieldScale()==0){
				javaTypeMap.put("jsonFormat", "@JsonSerialize(using=DecimalSerializer.class)");
				imports.add("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				imports.add(domain+".json.DecimalSerializer;");
			}else{
				javaTypeMap.put("jsonFormat", "@JsonSerialize(using=Decimal"+rule.getFieldScale()+"Serializer.class)");
				imports.add("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				imports.add(domain+".json.Decimal"+rule.getFieldScale()+"Serializer;");
			}
			javaTypeMap.put("excelFormat", "#");
			javaTypeMap.put("imports", imports);
		}else if("decimal".equals(type)){
			javaTypeMap.put("javaType", "Decimal");
			List<String> imports=new ArrayList<String>();
			imports.add("java.math.BigDecimal;");
			if(rule.getFieldScale()==null || rule.getFieldScale()==0){
				javaTypeMap.put("jsonFormat", "@JsonSerialize(using=DecimalSerializer.class)");
				imports.add("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				imports.add(domain+".json.DecimalSerializer;");
			}else{
				javaTypeMap.put("jsonFormat", "@JsonSerialize(using=Decimal"+rule.getFieldScale()+"Serializer.class)");
				imports.add("com.fasterxml.jackson.databind.annotation.JsonSerialize;");
				imports.add(domain+".json.Decimal"+rule.getFieldScale()+"Serializer;");
			}
			javaTypeMap.put("excelFormat", "#");
			javaTypeMap.put("imports", imports);
		}else if("year".equals(type)){
			javaTypeMap.put("javaType", "Short");
		}else if("date".equals(type)){
			javaTypeMap.put("javaType", "Date");
			javaTypeMap.put("jsonFormat", "@JsonFormat(pattern=\"yyyy-MM-dd\", timezone=\"GMT+8\")");
			List<String> imports=new ArrayList<String>();
			imports.add("java.util.Date;");
			imports.add("com.fasterxml.jackson.annotation.JsonFormat;");
		}else if("time".equals(type)){
			javaTypeMap.put("javaType", "Date");
			javaTypeMap.put("jsonFormat", "@JsonFormat(pattern=\"HH:mm:ss\", timezone=\"GMT+8\")");
			javaTypeMap.put("excelFormat", "HH:mm:ss");
			List<String> imports=new ArrayList<String>();
			imports.add("java.util.Date;");
			imports.add("com.fasterxml.jackson.annotation.JsonFormat;");
		}else if("datetime".equals(type)){
			javaTypeMap.put("javaType", "Date");
			javaTypeMap.put("jsonFormat", "@JsonFormat(pattern=\"yyyy-MM-dd HH:mm:ss\", timezone=\"GMT+8\")");
			javaTypeMap.put("excelFormat", "yyyy-MM-dd HH:mm:ss");
			List<String> imports=new ArrayList<String>();
			imports.add("java.util.Date;");
			imports.add("com.fasterxml.jackson.annotation.JsonFormat;");
		}else if("timestamp".equals(type)){
			javaTypeMap.put("javaType", "Date");
			javaTypeMap.put("jsonFormat", "@JsonFormat(pattern=\"yyyy-MM-dd HH:mm:ss\", timezone=\"GMT+8\")");
			javaTypeMap.put("excelFormat", "yyyy-MM-dd HH:mm:ss");
			List<String> imports=new ArrayList<String>();
			imports.add("java.util.Date;");
			imports.add("com.fasterxml.jackson.annotation.JsonFormat;");
		}else if("char".equals(type)){
			javaTypeMap.put("javaType", "String");
		}else{
			javaTypeMap.put("javaType", "String");
		}
		return javaTypeMap;
	}
	
	@ApiMethod(value="根据mysql列的字段列表确定需要继承的父实体类")
	public static Map<String, String> findParentEntity(List<Column> columnList, String coreEntityFields, String baseEntityFields, String sortEntityFields){
		Map<String, String> result=new HashMap<String, String>();
		if(!result.containsKey("extend")){
			if(ObjectUtils.isNotEmpty(sortEntityFields)){
				if(ObjectUtils.isNotEmpty(columnList)){
					int matchNumber=0;
					int allNumber=sortEntityFields.split("\\,").length;
					for (Column column : columnList) {
						if(column.getPrimaryKey()!=null && column.getPrimaryKey()){
							result.put("pkType", column.getFieldType());
						}
						if(StringUtils.contains(sortEntityFields, column.getFieldSampleName(), ",")){
							matchNumber++;
						}
					}
					if(matchNumber==allNumber){
						result.put("extend", "SortPo");
						result.put("import", "com.unswift.cloud.pojo.po.SortPo;");
						for (Column column : columnList) {
							if(StringUtils.contains(sortEntityFields, column.getFieldSampleName(), ",")){
								column.setGenericsField(false);
							}
						}
					}
				}
			}
		}
		if(!result.containsKey("extend")){
			if(ObjectUtils.isNotEmpty(baseEntityFields)){
				if(ObjectUtils.isNotEmpty(columnList)){
					int matchNumber=0;
					int allNumber=baseEntityFields.split("\\,").length;
					for (Column column : columnList) {
						if(column.getPrimaryKey()!=null && column.getPrimaryKey()){
							result.put("pkType", column.getFieldType());
						}
						if(StringUtils.contains(baseEntityFields, column.getFieldSampleName(), ",")){
							System.out.println(column.getFieldSampleName());
							matchNumber++;
						}
					}
					if(matchNumber==allNumber){
						result.put("extend", "BasePo");
						result.put("import", "com.unswift.cloud.pojo.po.BasePo;");
						for (Column column : columnList) {
							if(StringUtils.contains(baseEntityFields, column.getFieldSampleName(), ",")){
								column.setGenericsField(false);
							}
						}
					}
				}
			}
		}
		if(!result.containsKey("extend")){
			if(ObjectUtils.isNotEmpty(coreEntityFields)){
				if(ObjectUtils.isNotEmpty(columnList)){
					int matchNumber=0;
					int allNumber=coreEntityFields.split("\\,").length;
					for (Column column : columnList) {
						if(column.getPrimaryKey()!=null && column.getPrimaryKey()){
							result.put("pkType", column.getFieldType());
						}
						if(StringUtils.contains(coreEntityFields, column.getFieldSampleName(), ",")){
							matchNumber++;
						}
					}
					if(matchNumber==allNumber){
						result.put("extend", "CorePo");
						result.put("import", "com.unswift.cloud.pojo.po.CorePo;");
						for (Column column : columnList) {
							if(StringUtils.contains(coreEntityFields, column.getFieldSampleName(), ",")){
								column.setGenericsField(false);
							}
						}
					}
				}
			}
		}
		return result;
	}
	
	@ApiMethod(value="把列列表类需要导入的包统一放入导入列表中，重复的去掉")
	public static void setImportList(List<Column> columnList, List<String> importList){
		if(ObjectUtils.isNotEmpty(columnList)){
			for (Column column : columnList) {
				if(column.getGenericsField() && ObjectUtils.isNotEmpty(column.getImportPackageList())){
					for (String importPackage : column.getImportPackageList()) {
						if(!importList.contains(importPackage)){
							importList.add(importPackage);
						}
					}
				}
			}
		}
	}
	
	
	public static boolean isExistsIsDeleteField(List<Column> columnList){
		if(ObjectUtils.isEmpty(columnList)){
			return false;
		}
		for (Column column : columnList) {
			if(column.getFieldSampleName().equals("isDelete")){
				return true;
			}
		}
		return false;
	}
	
	public static String handleSubModule(String subModule) {
		if(ObjectUtils.isEmpty(subModule)) {
			return "";
		}
		StringBuilder module=new StringBuilder();
		String[] subModuleArray=subModule.split("\\.");
		for (String item : subModuleArray) {
			if(item.equals("class")) {
				module.append("classes.");
			}else {
				module.append(item).append(".");
			}
		}
		module.deleteCharAt(module.length()-1);
		return module.toString();
	}
	
	public static String addField(AddFieldRule rule) {
		StringBuilder result=new StringBuilder();
		String sql=createAddSql(rule);
		result.append("SQL：").append(sql).append(FileUtils.nextLine());
		try {
			DbSession.execute(sql);
			result.append("SQL：执行成功").append(FileUtils.nextLine());
		} catch (Exception e) {
			e.printStackTrace();
			result.append("SQL：执行失败，消息："+e.getMessage()).append(FileUtils.nextLine());
		}
		String subModule=rule.getCurrModule();
		String entitySampleName=StringUtils.underlineToHump(rule.getTable());
		String entityName=StringUtils.toFirstUpper(entitySampleName);
		
		Map<String, Object> javaTypeMap=columnTypeToJavaType(rule, rule.getBasePackage());
		
		String pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/po/"+rule.getModule()+"/"+entityName+".java";
		boolean exists=pojoFileAddField(pojoPath, rule, javaTypeMap, false, false, result);
		if(!exists) {
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"CreateBo.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, false, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportBo.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, false, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageBo.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, false, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateBo.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, false, false, result);
			
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"CreateDto.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, true, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportDto.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, true, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageDto.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, true, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateDto.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, true, false, result);
			
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageVo.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, true, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ViewVo.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, true, false, result);
			
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/mo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportMo.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, false, true, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/mo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportMo.java";
			pojoFileAddField(pojoPath, rule, javaTypeMap, false, true, result);
		}
		
		String mapperPath=rule.getProjectPath()+rule.getServerMapper()+"/src/main/resources/mapper/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"Mapper.xml";
		mapperFileAddField(mapperPath, rule, javaTypeMap, result);
		return result.toString();
	}
	
	@SuppressWarnings("unchecked")
	private static boolean pojoFileAddField(String filePath, AddFieldRule rule, Map<String, Object> javaTypeMap, boolean isJsonFormat, boolean isExcel, StringBuilder result) {
		File file=new File(filePath);
		if(!file.exists()) {
			result.append("POJO文件："+file.getAbsolutePath()+"不存在").append(FileUtils.nextLine());
			return true;
		}
		try {
			String content=FileUtils.reader(file, "UTF-8");
			String entityFieldSampleName=StringUtils.underlineToHump(rule.getFieldName());
			if(content.indexOf(" "+entityFieldSampleName+";")!=-1) {
				result.append("POJO文件："+file.getAbsolutePath()+"已存在此字段").append(FileUtils.nextLine());
				return true;
			}
			String entityAfterFieldSampleName=null;
			if(ObjectUtils.isNotEmpty(rule.getInsertAfter())) {
				entityAfterFieldSampleName=StringUtils.underlineToHump(rule.getInsertAfter());
			}
			List<String> importList=(List<String>)javaTypeMap.get("imports");
			if(isExcel || !isJsonFormat) {
				if(ObjectUtils.isNotEmpty(importList)) {
					importList=importList.stream().filter(i -> !i.contains("Serialize") && !i.contains("JsonFormat")).collect(Collectors.toList());
				}
			}
			if(ObjectUtils.isNotEmpty(importList)) {
				int index=content.lastIndexOf("import ");
				index=content.indexOf(FileUtils.nextLine(), index)+FileUtils.nextLine().length();
				String newContent=content.substring(0, index);
				for (String importClass : importList) {
					newContent+=importClass+FileUtils.nextLine();
				}
				newContent+=content.substring(index);
				content=newContent;
			}
			int index;
			if(ObjectUtils.isNotEmpty(entityAfterFieldSampleName)) {
				index=content.indexOf(" "+entityAfterFieldSampleName+";");
				if(index!=-1) {
					index=content.indexOf(FileUtils.nextLine(), index)+FileUtils.nextLine().length();
				}else {
					index=content.lastIndexOf("}");
					index=content.substring(0, index).lastIndexOf(FileUtils.nextLine());
				}
			}else {
				index=content.lastIndexOf("}");
				index=content.substring(0, index).lastIndexOf(FileUtils.nextLine());
			}
			String newContent=content.substring(0, index)+FileUtils.nextLine();
			newContent+="\t@ApiField(\""+rule.getFieldComment()+"\")"+FileUtils.nextLine();
			if(isExcel) {
				if(javaTypeMap.containsKey("excelFormat")) {
					newContent+="\t@ExcelColumn(value=\""+rule.getFieldComment()+"\", format=\""+javaTypeMap.get("excelFormat")+"\")"+FileUtils.nextLine();
				}else {
					newContent+="\t@ExcelColumn(\""+rule.getFieldComment()+"\")"+FileUtils.nextLine();
				}
			}else {
				if(isJsonFormat && javaTypeMap.containsKey("jsonFormat")) {
					newContent+="\t"+javaTypeMap.get("jsonFormat")+FileUtils.nextLine();
				}
			}
			newContent+="\tprivate "+javaTypeMap.get("javaType")+" "+entityFieldSampleName+";"+FileUtils.nextLine();
			newContent+=content.substring(index);
			FileUtils.writer(file, newContent, "UTF-8", false);
			result.append("POJO文件："+file.getAbsolutePath()+" 追加成功").append(FileUtils.nextLine());
		} catch (Exception e) {
			e.getMessage();
			result.append("POJO文件："+file.getAbsolutePath()+" 追加失败，消息："+e.getMessage());
		}
		return false;
	}
	
	private static void mapperFileAddField(String filePath, AddFieldRule rule, Map<String, Object> javaTypeMap, StringBuilder result) {
		File file=new File(filePath);
		if(!file.exists()) {
			result.append("Mapper文件："+file.getAbsolutePath()+"不存在").append(FileUtils.nextLine());
			return ;
		}
		String content=FileUtils.reader(file, "UTF-8");
		String fieldName=rule.getFieldName();
		if(content.indexOf("t."+fieldName+" ")!=-1) {
			result.append("Mapper文件："+file.getAbsolutePath()+"已存在此字段").append(FileUtils.nextLine());
			return ;
		}
		String entityFieldSampleName=StringUtils.underlineToHump(rule.getFieldName());
		String insertAfter=rule.getInsertAfter();
		String entityAfterFieldSampleName=null;
		if(ObjectUtils.isNotEmpty(insertAfter)) {
			entityAfterFieldSampleName=StringUtils.underlineToHump(rule.getInsertAfter());
		}
		int index=content.indexOf("<sql id=\"selectList\">");
		if(index!=-1) {//selectList
			int start;
			if(ObjectUtils.isNotEmpty(insertAfter)) {
				start=content.indexOf("t."+insertAfter+" ", index);
				if(start==-1) {
					start=content.indexOf("<if test=\"sql!=null and sql.selectList!=null\">", index);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				}else {
					start=content.indexOf(FileUtils.nextLine(), start)+FileUtils.nextLine().length();
				}
			}else {
				start=content.indexOf("<if test=\"sql!=null and sql.selectList!=null\">", index);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			}
			content=content.substring(0, start)+"\t\t\t,t."+fieldName+" `"+entityFieldSampleName+"`"+FileUtils.nextLine()+content.substring(start);
		}
		index=content.indexOf("<sql id=\"baseWhere\">");
		if(index!=-1) {//baseWhere
			int start;
			if(ObjectUtils.isNotEmpty(insertAfter)) {
				start=content.indexOf("t."+insertAfter+" ", index);
				if(start==-1) {
					start=content.indexOf("<include refid=\"sqlWhere\"/>", index);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				}else {
					start=content.indexOf(FileUtils.nextLine(), start)+FileUtils.nextLine().length();
				}
			}else {
				start=content.indexOf("<include refid=\"sqlWhere\"/>", index);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			}
			if("String".equals(javaTypeMap.get("javaType"))) {
				content=content.substring(0, start)+"\t\t\t\t<if test='"+entityFieldSampleName+" != null and "+entityFieldSampleName+"!=\"\"'>and t."+fieldName+" = #{"+entityFieldSampleName+"}</if>"+FileUtils.nextLine()+content.substring(start);
			}else {
				content=content.substring(0, start)+"\t\t\t\t<if test='"+entityFieldSampleName+" != null'>and t."+fieldName+" = #{"+entityFieldSampleName+"}</if>"+FileUtils.nextLine()+content.substring(start);
			}
		}
		index=content.indexOf("<insert id=\"insert\" useGeneratedKeys=\"true\" keyProperty=\"id\" keyColumn=\"id_\">");
		if(index!=-1) {//insert
			int start;
			if(ObjectUtils.isNotEmpty(insertAfter)) {
				start=content.indexOf("\t"+insertAfter+",", index);
				if(start==-1) {
					start=content.indexOf("</trim>", index);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				}else {
					start=content.indexOf(FileUtils.nextLine(), start)+FileUtils.nextLine().length();
				}
			}else {
				start=content.indexOf("</trim>", index);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			}
			content=content.substring(0, start)+"\t\t\t"+fieldName+","+FileUtils.nextLine()+content.substring(start);
			index=content.indexOf("<insert id=\"insert\" useGeneratedKeys=\"true\" keyProperty=\"id\" keyColumn=\"id_\">");
			index=content.indexOf("</trim>", index);
			index=content.indexOf("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">", index);
			if(ObjectUtils.isNotEmpty(entityAfterFieldSampleName)) {
				start=content.indexOf("#{"+entityAfterFieldSampleName+"},", index);
				if(start==-1) {
					start=content.indexOf("</trim>", index);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				}else {
					start=content.indexOf(FileUtils.nextLine(), start)+FileUtils.nextLine().length();
				}
			}else {
				start=content.indexOf("</trim>", index);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			}
			content=content.substring(0, start)+"\t\t\t#{"+entityFieldSampleName+"},"+FileUtils.nextLine()+content.substring(start);
		}
		index=content.indexOf("<insert id=\"insertBatch\" useGeneratedKeys=\"true\" keyProperty=\"list.id\" keyColumn=\"id_\">");
		if(index!=-1) {//insertBatch
			int start;
			if(ObjectUtils.isNotEmpty(insertAfter)) {
				start=content.indexOf("\t"+insertAfter+",", index);
				if(start==-1) {
					start=content.indexOf("</trim>", index);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				}else {
					start=content.indexOf(FileUtils.nextLine(), start)+FileUtils.nextLine().length();
				}
			}else {
				start=content.indexOf("</trim>", index);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			}
			content=content.substring(0, start)+"\t\t\t"+fieldName+","+FileUtils.nextLine()+content.substring(start);
			index=content.indexOf("<insert id=\"insertBatch\" useGeneratedKeys=\"true\" keyProperty=\"list.id\" keyColumn=\"id_\">");
			index=content.indexOf("</trim>", index);
			index=content.indexOf("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">", index);
			if(ObjectUtils.isNotEmpty(entityAfterFieldSampleName)) {
				start=content.indexOf("#{item."+entityAfterFieldSampleName+"},", index);
				if(start==-1) {
					start=content.indexOf("</trim>", index);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				}else {
					start=content.indexOf(FileUtils.nextLine(), start)+FileUtils.nextLine().length();
				}
			}else {
				start=content.indexOf("</trim>", index);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			}
			content=content.substring(0, start)+"\t\t\t\t#{item."+entityFieldSampleName+"},"+FileUtils.nextLine()+content.substring(start);
		}
		index=content.indexOf("<update id=\"update\">");
		if(index!=-1) {//baseWhere
			int start;
			if(ObjectUtils.isNotEmpty(insertAfter)) {
				start=content.indexOf(">"+insertAfter+" =", index);
				if(start==-1) {
					start=content.indexOf("</set>", index);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				}else {
					start=content.indexOf(FileUtils.nextLine(), start)+FileUtils.nextLine().length();
				}
			}else {
				start=content.indexOf("</set>", index);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			}
			content=content.substring(0, start)+"\t\t\t<if test=\""+entityFieldSampleName+" != null\">"+fieldName+" = #{"+entityFieldSampleName+"},</if>"+FileUtils.nextLine()+content.substring(start);
		}
		index=content.indexOf("<update id=\"updateBatch\">");
		if(index!=-1) {//baseWhere
			int start;
			if(ObjectUtils.isNotEmpty(insertAfter)) {
				start=content.indexOf(">"+insertAfter+" =", index);
				if(start==-1) {
					start=content.indexOf("</set>", index);
					start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				}else {
					start=content.indexOf(FileUtils.nextLine(), start)+FileUtils.nextLine().length();
				}
				content=content.substring(0, start)+"\t\t\t\t<if test=\"item."+entityFieldSampleName+" != null\">"+fieldName+" = #{item."+entityFieldSampleName+"},</if>"+FileUtils.nextLine()+content.substring(start);
			}else {
				start=content.indexOf("</set>", index);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			}
		}
		FileUtils.writer(file, content, "UTF-8", false);
		result.append("Mapper文件："+file.getAbsolutePath()+" 追加成功").append(FileUtils.nextLine());
	}
	
	private static String createAddSql(AddFieldRule rule) {
		StringBuilder sql=new StringBuilder();
		sql.append("ALTER TABLE");//alter table
		sql.append(" `").append(rule.getDatabase()).append("`.`").append(rule.getTable()).append("`");//table
		sql.append(" ADD `").append(rule.getFieldName()).append("`");//add field
		sql.append(" ").append(rule.getFieldType());//int|varchar|bigint...
		if(ObjectUtils.isNotEmpty(rule.getFieldLength())) {//(n,m)
			sql.append("(").append(rule.getFieldLength());
			if(ObjectUtils.isNotEmpty(rule.getFieldScale())) {
				sql.append(",").append(rule.getFieldScale());
			}
			sql.append(")");
		}else if(ObjectUtils.isNotEmpty(rule.getFieldValue())) {//(s1,s2,s3...)
			sql.append("(").append(rule.getFieldValue()).append(")");
		}
		sql.append(" COMMENT '").append(rule.getFieldComment().replace("'", "\\'")).append("'");//comment
		if(ObjectUtils.isNotEmpty(rule.getFieldDefault())) {
			if("bit".equals(rule.getFieldType())) {
				sql.append(" DEFAULT b'").append(rule.getFieldDefault()).append("'");
			}else {
				sql.append(" DEFAULT '").append(rule.getFieldDefault().replace("'", "\\'")).append("'");
			}
		}
		if(ObjectUtils.isNotEmpty(rule.getInsertAfter())) {
			sql.append(" AFTER `").append(rule.getInsertAfter()).append("`");
		}
		sql.append(";");
		return sql.toString();
	}
	
	public static String dropField(DropFieldRule rule) {
		StringBuilder result=new StringBuilder();
		String sql=createDropSql(rule);
		result.append("SQL：").append(sql).append(FileUtils.nextLine());
		try {
			DbSession.execute(sql);
			result.append("SQL：执行成功").append(FileUtils.nextLine());
		} catch (Exception e) {
			e.printStackTrace();
			result.append("SQL：执行失败，消息："+e.getMessage()).append(FileUtils.nextLine());
		}
		String subModule=rule.getCurrModule();
		String entitySampleName=StringUtils.underlineToHump(rule.getTable());
		String entityName=StringUtils.toFirstUpper(entitySampleName);
		
		//Map<String, Object> javaTypeMap=columnTypeToJavaType(rule, rule.getBasePackage());
		
		String pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/po/"+rule.getModule()+"/"+entityName+".java";
		boolean exists=pojoFileDropField(pojoPath, rule, false, false, result);
		if(!exists) {
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"CreateBo.java";
			pojoFileDropField(pojoPath, rule, false, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportBo.java";
			pojoFileDropField(pojoPath, rule, false, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageBo.java";
			pojoFileDropField(pojoPath, rule, false, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/bo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateBo.java";
			pojoFileDropField(pojoPath, rule, false, false, result);
			
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"CreateDto.java";
			pojoFileDropField(pojoPath, rule, true, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportDto.java";
			pojoFileDropField(pojoPath, rule, true, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageDto.java";
			pojoFileDropField(pojoPath, rule, true, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/dto/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"UpdateDto.java";
			pojoFileDropField(pojoPath, rule, true, false, result);
			
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"PageVo.java";
			pojoFileDropField(pojoPath, rule, true, false, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/vo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ViewVo.java";
			pojoFileDropField(pojoPath, rule, true, false, result);
			
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/mo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ExportMo.java";
			pojoFileDropField(pojoPath, rule, false, true, result);
			pojoPath=rule.getProjectPath()+rule.getServerPojo()+"/src/main/java/"+rule.getBasePackage().replace(".", "/")+"/pojo/mo/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"ImportMo.java";
			pojoFileDropField(pojoPath, rule, false, true, result);
		}
		
		String mapperPath=rule.getProjectPath()+rule.getServerMapper()+"/src/main/resources/mapper/"+rule.getModule()+"/"+subModule.replace('.','/')+"/"+entityName+"Mapper.xml";
		mapperFileDropField(mapperPath, rule, result);
		return result.toString();
	}
	
	private static String createDropSql(DropFieldRule rule) {
		StringBuilder sql=new StringBuilder();
		sql.append("ALTER TABLE");//alter table
		sql.append(" `").append(rule.getDatabase()).append("`.`").append(rule.getTable()).append("`");//table
		sql.append(" DROP COLUMN `").append(rule.getFieldName()).append("`");//drop field
		sql.append(";");
		return sql.toString();
	}
	
	private static boolean pojoFileDropField(String filePath, DropFieldRule rule, boolean isJsonFormat, boolean isExcel, StringBuilder result) {
		File file=new File(filePath);
		if(!file.exists()) {
			result.append("POJO文件："+file.getAbsolutePath()+"不存在").append(FileUtils.nextLine());
			return true;
		}
		try {
			String content=FileUtils.reader(file, "UTF-8");
			String entityFieldSampleName=StringUtils.underlineToHump(rule.getFieldName());
			if(content.indexOf(" "+entityFieldSampleName+";")==-1) {
				result.append("POJO文件："+file.getAbsolutePath()+"已删除此字段").append(FileUtils.nextLine());
				return true;
			}
			int index=content.indexOf(" "+entityFieldSampleName+";");
			String subContent = content.substring(0, index);
			int start=subContent.lastIndexOf(FileUtils.nextLine());
			int first=subContent.substring(0, start).lastIndexOf(FileUtils.nextLine());
			while(content.substring(first, start).contains("\t@")) {
				start=first;
				first=subContent.substring(0, start).lastIndexOf(FileUtils.nextLine());
			}
			int end=content.indexOf(FileUtils.nextLine(), index)+FileUtils.nextLine().length();
			content=content.substring(0, start)+content.substring(end);
			FileUtils.writer(file, content, "UTF-8", false);
			result.append("POJO文件："+file.getAbsolutePath()+" 删除成功").append(FileUtils.nextLine());
		} catch (Exception e) {
			e.getMessage();
			result.append("POJO文件："+file.getAbsolutePath()+" 删除失败，消息："+e.getMessage());
		}
		return false;
	}
	
	private static void mapperFileDropField(String filePath, DropFieldRule rule, StringBuilder result) {
		File file=new File(filePath);
		if(!file.exists()) {
			result.append("Mapper文件："+file.getAbsolutePath()+"不存在").append(FileUtils.nextLine());
			return ;
		}
		String content=FileUtils.reader(file, "UTF-8");
		String fieldName=rule.getFieldName();
		if(content.indexOf("t."+fieldName+" ")==-1) {
			result.append("Mapper文件："+file.getAbsolutePath()+"已删除此字段").append(FileUtils.nextLine());
			return ;
		}
		String entityFieldSampleName=StringUtils.underlineToHump(rule.getFieldName());
		int index=content.indexOf("<sql id=\"selectList\">");
		if(index!=-1) {//selectList
			int start=content.indexOf("t."+fieldName+" ", index);
			int end=content.indexOf(FileUtils.nextLine(), start);
			start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
			content=content.substring(0, start)+content.substring(end);
		}
		index=content.indexOf("<sql id=\"baseWhere\">");
		if(index!=-1) {//baseWhere
			int start=content.indexOf("t."+fieldName+" ", index);
			if(start!=-1) {
				int end=content.indexOf(FileUtils.nextLine(), start);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				content=content.substring(0, start)+content.substring(end);
			}
		}
		index=content.indexOf("<insert id=\"insert\" useGeneratedKeys=\"true\" keyProperty=\"id\" keyColumn=\"id_\">");
		if(index!=-1) {//insert
			int start=content.indexOf("\t"+fieldName+",", index);
			if(start!=-1) {
				int end=content.indexOf(FileUtils.nextLine(), start);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				content=content.substring(0, start)+content.substring(end);
				index=content.indexOf("</trim>", index);
				index=content.indexOf("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">", index);
				start=content.indexOf("#{"+entityFieldSampleName+"},", index);
				end=content.indexOf(FileUtils.nextLine(), start);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				content=content.substring(0, start)+content.substring(end);
			}
		}
		index=content.indexOf("<insert id=\"insertBatch\" useGeneratedKeys=\"true\" keyProperty=\"list.id\" keyColumn=\"id_\">");
		if(index!=-1) {//insertBatch
			int start=content.indexOf("\t"+fieldName+",", index);
			if(start!=-1) {
				int end=content.indexOf(FileUtils.nextLine(), start);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				content=content.substring(0, start)+content.substring(end);
				index=content.indexOf("</trim>", index);
				index=content.indexOf("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">", index);
				start=content.indexOf("#{item."+entityFieldSampleName+"},", index);
				end=content.indexOf(FileUtils.nextLine(), start);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				content=content.substring(0, start)+content.substring(end);
			}
		}
		index=content.indexOf("<update id=\"update\">");
		if(index!=-1) {//baseWhere
			int start=content.indexOf(">"+fieldName+" =", index);
			if(start!=-1) {
				int end=content.indexOf(FileUtils.nextLine(), start);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				content=content.substring(0, start)+content.substring(end);
			}
		}
		index=content.indexOf("<update id=\"updateBatch\">");
		if(index!=-1) {//baseWhere
			int start=content.indexOf(">"+fieldName+" =", index);
			if(start!=-1) {
				int end=content.indexOf(FileUtils.nextLine(), start);
				start=content.substring(0, start).lastIndexOf(FileUtils.nextLine(), start);
				content=content.substring(0, start)+content.substring(end);
			}
		}
		FileUtils.writer(file, content, "UTF-8", false);
		result.append("Mapper文件："+file.getAbsolutePath()+" 删除成功").append(FileUtils.nextLine());
	}
}
